package oop.ex3.serverprotocol;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import oop.ex3.nameserver.NameServer;
import oop.ex3.sharedclasses.IPaddress;

/**
 * Handles Messages received from clients.
 * Handles a client's message (from the server's side).
 * for example Begin, extending ClientMessage, will represent the NS's
 * response to a Begin message from the Client.
 * Also contains final Strings representing the known messages
 * in the system.
 * @author zablo
 */
public abstract class ClientMessageHandler {
	
	static final boolean SUCCESS=true,FAILURE=false;
	
	static final String END="END"; // End of message
	
	// Known client Messages
	public static final String END_LIST="ENDLIST", //End of list
						CONTAIN_FILE="CONTAINFILE", // Client contains a file
						DONT_CONTAIN_FILE="DONTCONTAINFILE", // client doesn't contain a file
						CONTAIN_NAME_SERVER="CONTAINNAMESERVER", //contains name server message
						END_SESSION="ENDSESSION", //Ends the session
						GO_AWAY="GOAWAY", //tells the server to go down
						GOODBYE="GOODBYE", //client is disconnecting from server
						WANT_ALL_FILES="WANTALLFILES", //request all server's files
						WANT_FILE="WANTFILE",// request sources for certain file
						WANT_SERVERS="WANTSERVERS", // request nameservers
						BEGIN="BEGIN";
	//TODO add known client messages
	
	
	/**
	 * Handles the client's Message.
	 * Implemented differently for each client message.
	 * Also reads the parameters.
	 * @param server the NameServer to which the Message was sent.
	 * @param sessionIP the IP of the client in the session in which the message
	 * 				 	was sent.
	 * @param clientInput the Client's input stream.
	 * @param clientOutput the Client's output stream.
	 * @return SUCCESS(true) if the operation completed successfully
	 * 			FAILURE(false) otherwise.
	 */
	public abstract boolean run(NameServer server, IPaddress sessionIP, 
								DataInputStream clientInput, DataOutputStream clientOutput);
	
	/**
	 * Handles the end of a Message.
	 * Will return SUCCESS if the END indeed appears at the end of the Message,
	 * or FAILURE otherwise.
	 * @param clientInput the client's input stream (input source).
	 * @return SUCCESS if END appears in the end, FAILURE otherwise (including
	 * 				errors in reading the END).
	 */
	protected boolean endsWithEnd(DataInputStream clientInput){
		try {
			if (!clientInput.readUTF().equals(END)){
				return FAILURE;
			}
			else
				return SUCCESS;
		} catch (IOException e) {
				return FAILURE;
		}
	}
}
